
package com.john.blog.controller.back;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;

import com.john.blog.common.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.john.blog.common.constant.KeyConst;
import com.john.blog.common.constant.ModelDictionary;
import com.john.blog.common.vo.CommonResult;
import com.john.blog.common.vo.FtpConfig;
import com.john.blog.common.vo.RemoteConfig;
import com.john.blog.controller.back.support.AbstractBackModelControllerSupport;
import com.john.blog.model.po.Blog;
import com.john.blog.model.po.Category;
import com.john.blog.model.po.Tags;
import com.john.blog.model.po.Type;
import com.john.blog.service.BlogService;
import com.john.blog.service.CategoryService;
import com.john.blog.service.TagsService;
import com.john.blog.service.TypeService;

import tk.mybatis.mapper.entity.Example;

/**
 * 博客controller
 * 
 * @author JiangGengchao
 * @date 2018年2月25日
 */
@RestController
@RequestMapping("/blog/back/blog")
public class BackBlogController extends AbstractBackModelControllerSupport<Blog> {

    private Logger log = LoggerFactory.getLogger(BackBlogController.class);

    @Value("${remote.server}")
    private String REMOTE_SERVER;
    @Value("${remote.port}")
    private Integer REMOTE_PORT;
    @Value("${remote.username}")
    private String REMOTE_USERNAME;
    @Value("${remote.password}")
    private String REMOTE_PASSWORD;
    @Value("${remote.default-path}")
    private String DEFAULT_PATH;
    @Value("${server.config-path}")
    private String CONFIG_PATH;
    @Value("${remote.need-delete}")
    private Boolean NEED_DELETE;

    @Autowired
    private HttpServletRequest request;
    @Autowired
    private BlogService blogService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private TypeService typeService;
    @Autowired
    private TagsService tagsService;

    @PostConstruct
    public void init() {
        this.service = blogService;
    }

    @RequestMapping("/add")
    @Override
    public CommonResult add(Blog blog) {
        String signature = KeyUtils.signByMD5(blog.getContent() + blog.getName());
        // 查询签名是否已经存在
        Example example = new Example(Blog.class);
        example.createCriteria().andEqualTo("signature", signature);
        List<Blog> blogs = blogService.selectByExample(example);
        if (DetectUtils.notEmpty(blogs)) {
            return CommonResult.build(CommonResult.Code.EXISTS);
        }
        if (DetectUtils.isEmpty(blog.getId())) {
            blog.setId(KeyUtils.getUUID());
        }
        blog.setSignature(signature);
        blog.setReadNum(0);
        blog.setCommentNum(0);
        blog.setHeartNum(0);
        blog.setShareNum(0);

        Date curDate = new Date();
        blog.setCreateDate(curDate);
        blog.setUpdateDate(curDate);

        String fileName = StaticsUtils.genHtmlFileName(curDate);
        // html文件存储路径
        blog.setRemoteUrl(REMOTE_SERVER + KeyConst.TEMPLATE_PATH + "/" + fileName);
        // html文件url路径
        blog.setUrl(KeyConst.BLOG_URL + "/" + fileName.split("\\.")[0]);

        try {
            // 修改类别中的博文数
            Category category = categoryService.selectByPrimaryKey(blog.getCategoryID());
            if (null != category) {
                Type type = typeService.selectByPrimaryKey(category.getTypeID());
                if (null != type) {
                    blog.setCategoryName(category.getName());
                    blog.setTypeName(type.getName());
                    service.insert(blog);
                    category.setBlogNum(category.getBlogNum() + 1);
                    categoryService.updateByPrimaryKeySelective(category);
                    // 保存标签
                    if (blog.getTags() != null) {
                        String[] arr = blog.getTags().split(",");
                        for (String tag : arr) {
                            if (DetectUtils.isEmpty(tag)) {
                                continue;
                            }
                            String tagID = KeyUtils.signByMD5(tag);
                            Tags ttag = tagsService.selectByPrimaryKey(tagID);
                            if (ttag == null) {
                                ttag = new Tags();
                                ttag.setId(tagID);
                                ttag.setName(tag);
                                Date date = new Date();
                                ttag.setCreateDate(date);
                                ttag.setUpdateDate(date);
                                ttag.setBlogNum(1);
                                tagsService.insert(ttag);
                            } else {
                                ttag.setBlogNum(ttag.getBlogNum() + 1);
                                tagsService.updateByPrimaryKeySelective(ttag);
                            }
                        }
                    }
                } else {
                    return CommonResult.error(category.getName() + ",此分类没有制定类型");
                }
            } else {
                return CommonResult.error("未设置文章类型");
            }

            if (blog.getStatus() == ModelDictionary.BLOG_STATUS.DISPLAY) {
                /* 静态化处理 */
                if (!statics(blog)) { // 静态化处理失败
                    return CommonResult.build(CommonResult.Code.STATICS_ERROR);
                }
            }
            return CommonResult.success(blog);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return CommonResult.error(e.getMessage());
        }
    }

    @RequestMapping("/del")
    @Override
    public CommonResult del(String id) {
        Blog blog = blogService.selectByPrimaryKey(id);
        if (blog == null) {
            return CommonResult.error("要删除的博客不存在");
        }
        // 删除流程：1.删除http服务器静态资源，2.类别数减1 3.删除博文
        try {
            FtpConfig ftpConfig = new FtpConfig(REMOTE_SERVER.split("//")[1], REMOTE_PORT, REMOTE_USERNAME, REMOTE_PASSWORD, DEFAULT_PATH + KeyConst.TEMPLATE_PATH, "utf-8");
            FtpUtil.deleteFile(ftpConfig, blog.getRemoteUrl().substring(blog.getRemoteUrl().lastIndexOf("/") + 1));
            Category category = categoryService.selectByPrimaryKey(blog.getCategoryID());
            category.setBlogNum(category.getBlogNum() - 1);
            categoryService.updateByPrimaryKeySelective(category);
            return super.del(id);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return CommonResult.error("静态文件删除失败,博客删除失败！！！");
        }
    }

    @RequestMapping("/get")
    @Override
    public CommonResult get(String id) {
        try {
            Map<String, Object> result = new HashMap<>();
            Blog data = service.selectByPrimaryKey(id);
            List<Category> categoryList = categoryService.findAll();
            if (null != data) {
                result.put("blog", data);
                result.put("categorys", categoryList);
                return CommonResult.success(result);
            } else {
                return CommonResult.error("没有查询到对象");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return CommonResult.error("查询失败");
        }
    }

    @RequestMapping("/edit")
    @Override
    public CommonResult edit(Blog newBlog) {
        String signature = KeyUtils.signByMD5(newBlog.getContent() + newBlog.getName());
        newBlog.setSignature(signature);
        newBlog.setReadNum(0);
        newBlog.setCommentNum(0);
        newBlog.setHeartNum(0);
        newBlog.setShareNum(0);

        Date curDate = new Date();
        newBlog.setCreateDate(curDate);
        newBlog.setUpdateDate(curDate);
        String fileName = StaticsUtils.genHtmlFileName(curDate);
        // html文件存储路径
        newBlog.setRemoteUrl(REMOTE_SERVER + KeyConst.TEMPLATE_PATH + "/" + fileName);
        // html文件url路径
        newBlog.setUrl(KeyConst.BLOG_URL + "/" + fileName.split("\\.")[0]);

        Blog oldBlog = blogService.selectByPrimaryKey(newBlog.getId());
        if (oldBlog == null) {
            return CommonResult.error("文章不存在");
        }
        // 更新流程：1.处理类别：类别中博文数 2.处理标签:解除映射关系 3.更新博客，重新静态化
        // 处理类别
        if (!oldBlog.getCategoryID().equals(newBlog.getCategoryID())) {
            Category c1 = categoryService.selectByPrimaryKey(oldBlog.getCategoryID());
            Category c2 = categoryService.selectByPrimaryKey(newBlog.getCategoryID());
            newBlog.setCategoryName(c2.getName());
            Type type = typeService.selectByPrimaryKey(c2.getTypeID());
            if (null != type) {
                newBlog.setTypeName(type.getName());
            }
            c1.setBlogNum(c1.getBlogNum() - 1);
            c2.setBlogNum(c2.getBlogNum() + 1);
            categoryService.updateByPrimaryKeySelective(c1);
            categoryService.updateByPrimaryKeySelective(c2);
        }
        // 处理标签
        doHandleTag(oldBlog, newBlog);

        if (newBlog.getStatus() == ModelDictionary.BLOG_STATUS.DISPLAY) {
            /* 静态化处理 */
            if (!statics(newBlog)) { // 静态化处理失败
                return CommonResult.build(CommonResult.Code.STATICS_ERROR);
            }
        }
        FtpConfig ftpConfig = new FtpConfig(REMOTE_SERVER.split("//")[1], REMOTE_PORT, REMOTE_USERNAME, REMOTE_PASSWORD, DEFAULT_PATH + KeyConst.TEMPLATE_PATH, "utf-8");
        try {
            FtpUtil.deleteFile(ftpConfig, oldBlog.getRemoteUrl().substring(oldBlog.getRemoteUrl().lastIndexOf("/") + 1));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
       return super.edit(newBlog);
    }

    @RequestMapping("/restaticsAll")
    public CommonResult restaticsAll() {
        List<Blog> blogs = blogService.findAll();
        String errorMsg = "";
        for (Blog blog : blogs) {
            log.info("开始静态化" + blog.getName());
            if (!statics(blog)) {
                errorMsg += "博客" + blog.getId() + "静态化失败;";
            } else {
                log.info(blog.getName() + "静态化成功");
            }
        }
        if (DetectUtils.notEmpty(errorMsg)) {
            return CommonResult.error(errorMsg);
        }
        return CommonResult.success();
    }

    /**
     * 处理tag修改
     * 
     * @param blog
     * @return
     */
    private void doHandleTag(Blog oldBlog, Blog newBlog) {
        if (newBlog.getTags() != null) {
            String[] arr = newBlog.getTags().split(",");
            if (DetectUtils.notEmpty(arr)) {
                for (String tag : arr) {
                    if (DetectUtils.isEmpty(tag)) {
                        continue;
                    }
                    String tagID = KeyUtils.signByMD5(tag);
                    Tags ttag = tagsService.selectByPrimaryKey(tagID);
                    if (ttag == null) {
                        ttag = new Tags();
                        ttag.setId(tagID);
                        ttag.setName(tag);
                        Date date = new Date();
                        ttag.setCreateDate(date);
                        ttag.setUpdateDate(date);
                        ttag.setBlogNum(1);
                        tagsService.insert(ttag);
                    } else {
                        ttag.setBlogNum(ttag.getBlogNum() + 1);
                        tagsService.updateByPrimaryKeySelective(ttag);
                    }
                }
            }
        }
        if (oldBlog.getTags() != null) {
            String[] arr = newBlog.getTags().split(",");
            if (DetectUtils.notEmpty(arr)) {
                for (String tag : arr) {
                    if (DetectUtils.isEmpty(tag)) {
                        continue;
                    }
                    String tagID = KeyUtils.signByMD5(tag);
                    Tags ttag = tagsService.selectByPrimaryKey(tagID);
                    if (ttag != null) {
                        ttag.setBlogNum(ttag.getBlogNum() - 1);
                        if (ttag.getBlogNum() > 0) {
                            tagsService.updateByPrimaryKeySelective(ttag);
                        } else {
                            tagsService.deleteByPrimaryKey(ttag.getId());
                        }
                    }
                }
            }
        }
    }

    /**
     * 静态化博客
     * 
     * @param blog
     * @return
     */
    private boolean statics(Blog blog) {
        boolean st = false;
        try {
            RemoteConfig remoteConfig = new RemoteConfig(REMOTE_SERVER, REMOTE_USERNAME, REMOTE_PORT, REMOTE_PASSWORD, NEED_DELETE, DEFAULT_PATH, CONFIG_PATH);
            st = StaticsUtils.render(remoteConfig, RequestUtils.getBasePath(request), blogService, blog);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return st;
    }

}
